#include "umlgraphicsitem.h"

#include "uml/umldiritem.h"

UmlGraphicsItem::UmlGraphicsItem(UmlProject *project) : UmlItem(project)
{
    this->_itemTypeFlags |= UmlItem::UmlGraphicsItemType;

    // init parent directory
    this->_parentDir = 0;

    // items are movable and selectable
    QGraphicsItem::setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
    this->setAcceptHoverEvents(true);

    // setting graphics effects
    this->setCacheMode(QGraphicsItem::DeviceCoordinateCache);

    // init mouse flags
    this->_isHovered = false;
    this->_isPressed = false;

    this->_borderPen.setWidth(1);
    this->_borderPen.setColor(Qt::black);
    this->_borderPen.setJoinStyle(Qt::MiterJoin);

    this->_borderItem.setPen(this->_borderPen);
    this->_borderItem.setParentItem(this);
}

UmlDirItem* UmlGraphicsItem::parentDir()
{
    return this->_parentDir;
}

void UmlGraphicsItem::setParentDir(UmlDirItem *dir)
{
    this->_parentDir = dir;
}

QRectF UmlGraphicsItem::boundingRect() const
{
    return this->_boundingRect;
}

QVariant UmlGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if (change == QGraphicsObject::ItemSceneHasChanged) {

        this->_borderItem.setParentItem(this);
        this->addToGroup(&this->_borderItem);

        emit this->updateUmlText();
    }

    if (change == QGraphicsObject::ItemSelectedHasChanged) {
        if (value.toBool()) {
            QPen pen(this->_borderPen);
            pen.setWidth(3);
            this->_borderItem.setPen(pen);
        } else {
            this->_borderItem.setPen(this->_borderPen);
        }
    }

    return QGraphicsItemGroup::itemChange(change, value);
}


void UmlGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    this->_isHovered = true;
    QGraphicsItemGroup::hoverEnterEvent(event);
}

void UmlGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    QGraphicsItemGroup::hoverMoveEvent(event);
}

void UmlGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    this->_isHovered = false;
    QGraphicsItemGroup::hoverLeaveEvent(event);
}

void UmlGraphicsItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    if (event->reason() == QGraphicsSceneContextMenuEvent::Mouse) {
        QList<QAction*> actions = this->contextActions();

        if (!actions.isEmpty()) {
            QMenu menu;
            menu.addActions(actions);
            menu.exec(event->screenPos());
        }
    }
}

QList<QAction*> UmlGraphicsItem::contextActions()
{
    QList<QAction*> actions;

    QAction *removeAction = new QAction(QObject::tr("remove"), this);
    removeAction->setIcon(QIcon(":icons/contextmenu/remove.png"));
    QObject::connect(removeAction, SIGNAL(triggered()), this, SLOT(remove()));

    actions.prepend(removeAction);

    return actions;
}

void UmlGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->fillRect(this->_boundingRect, Qt::white);

    QGraphicsItemGroup::paint(painter, option, widget);
}

void UmlGraphicsItem::remove()
{
    this->_project->removeUmlItem(this);
}

int UmlGraphicsItem::row() const
{
    if (this->_parentDir != 0) {
        return this->_parentDir->items().indexOf(const_cast<UmlGraphicsItem*>(this));
    }

    return 0;
}

QModelIndex UmlGraphicsItem::modelIndex()
{
    return this->_index;
}

void UmlGraphicsItem::setModelIndex(QModelIndex index)
{
    this->_index = index;
}

ItemDragEffect* UmlGraphicsItem::acceptDropEffect()
{
    ItemDragEffect *effect = new ItemDragEffect(this);

    effect->setAcceptDrop(true);

    return effect;
}

ItemDragEffect* UmlGraphicsItem::denyDropEffect()
{
    ItemDragEffect *effect = new ItemDragEffect(this);

    effect->setAcceptDrop(false);

    return effect;
}
